#include <stdio.h>
#include <stdlib.h>
#include "dominion.h"
#include "dominion_helpers.h"
#include "rngs.h"

//This Unit Test Will Test the scoreFor() Function.
#define MAX_CARD treasure_map

//initialize game struct to array of 0's
void clearGameState(struct gameState *G) {
  int i;
	for (i=0; i<sizeof(struct gameState); i++) {
		((char *)G)[i] = 0;
	}
}

int main() {	

	int i, j;
	int currentPlayer, handCount, deckCount, discardCount;	//relevant to scoreFor() in dominion.c
	int card;
	int cardValues[MAX_CARD+1];	//stores treasure point values for ALL cards in game
	int seed = 1003;		//FEEL FREE TO CHANGE
	int num_tests = 100;		//FEEL FREE TO CHANGE
	int theoreticalScore, testScore;
	int errors = 0;
	struct gameState G;
	
	//initialize random number using rngs.c library
	SelectStream(1);
	PutSeed((long)seed);
	
	printf("Now Testing unittest 2: scoreFor() Function\n");
	//this game only awards points for treasure cards, so only explicitly specify those values as non-zero and initialize the rest to 0
	for (i=0; i < MAX_CARD + 1; i++) {
	    cardValues[i] = 0;
	}
	
	cardValues[estate] = 1;
	cardValues[great_hall] = 1;
	cardValues[duchy] = 3;
	cardValues[province] = 6;
	cardValues[curse] = -1;
	
	for (i=0; i < num_tests; i++) {
	  
	  theoreticalScore = 0;
	  clearGameState(&G);		//blank the game state to all zeros
	  
	  //get a random player number, handCount, deckCount, discardCount 
	  currentPlayer = (int)(Random()*3)+1;
	  
	  handCount = (int)(Random()*(MAX_DECK/3));
	  discardCount = (int)(Random()*(MAX_DECK/3));
	  deckCount = (int)(Random()*(MAX_DECK/3));
	  
	  //Create a hand, deck, and discard pile:
	  //Hand
	  for (j=0; j < handCount; j++) {
	     card = (int)(Random()*MAX_CARD);		//random card
	     theoreticalScore += cardValues[card];	//update score
	     G.hand[currentPlayer][j] = card;		//place card in handCount
	  }
	  
	  //Deck
	  for (j=0; j < deckCount; j++) {
	     card = (int)(Random()*MAX_CARD);		//random card
	     theoreticalScore += cardValues[card];	//update score
	     G.deck[currentPlayer][j] = card;		//place card in deck
	  }
	  
	  
	  //Discard
	  for (j=0; j < discardCount; j++) {
	     card = (int)(Random()*MAX_CARD);		//random card
	     theoreticalScore += cardValues[card];	//update score
	     G.discard[currentPlayer][j] = card;	//place card in discard
	  }
	  
	  //prepare function call for scoreFor by placing values in appropriate gameState position
	  G.handCount[currentPlayer] = handCount;
	  G.deckCount[currentPlayer] = deckCount;
	  G.discardCount[currentPlayer] = discardCount;
	  
	  //call scoreFor function
	  testScore = scoreFor(currentPlayer, &G);
	  
	  //Compare theoretical score with the function call from dominion.c
	  if (testScore != theoreticalScore) {
	    printf("Error: Expected score of %d, but scoreFor returned %d\n", theoreticalScore, testScore);
	    errors++;
	  }
	} // end main loop
	
	printf("Out of %d tests, %d returned error\n\n", num_tests, errors);

	return 0;
}